package cmpe451.group7.ourcity.beans;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.primefaces.event.map.OverlaySelectEvent;
import org.primefaces.event.map.PointSelectEvent;
import org.primefaces.model.map.DefaultMapModel;
import org.primefaces.model.map.LatLng;
import org.primefaces.model.map.MapModel;
import org.primefaces.model.map.Marker;
import org.springframework.util.StringUtils;

import cmpe451.group7.ourcity.dao.PlaceDAO;
import cmpe451.group7.ourcity.dao.UserDAO;
import cmpe451.group7.ourcity.entity.Place;
import cmpe451.group7.ourcity.entity.Tag;
import cmpe451.group7.ourcity.entity.User;
import cmpe451.group7.ourcity.recommendation.FreebaseQuery;
import cmpe451.group7.ourcity.service.PlaceService;

/**
 * Search bean for using in the search page of the web site.
 */
/**
 * @author RamiGökhan
 * 
 */
@ManagedBean
@ViewScoped
public class AddPlaceBean implements Serializable {

	private static final long serialVersionUID = -3106395871039054455L;

	@ManagedProperty(value = "#{placeDAO}")
	private PlaceDAO placeDAO;

	@ManagedProperty(value = "#{userDAO}")
	private UserDAO userDAO;

	@ManagedProperty(value = "#{placeService}")
	private PlaceService placeService;

	private MapModel map;
	private Marker marker;

	private String country;
	private String city;

	private double latitude;
	private double longitude;

	private String placeName;
	private List<Tag> tags;

	@ManagedProperty(value = "#{loginBean}")
	private LoginBean loginBean;

	public AddPlaceBean() {
		map = new DefaultMapModel();
	}

	public String getCountry() {
		return country;
	}

	public void setCountry(String country) {
		this.country = country;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public double getLatitude() {
		return latitude;
	}

	public void setLatitude(double latitude) {
		this.latitude = latitude;
	}

	public double getLongitude() {
		return longitude;
	}

	public void setLongitude(double longitude) {
		this.longitude = longitude;
	}

	public String getPlaceName() {
		return placeName;
	}

	public void setPlaceName(String placeName) {
		this.placeName = placeName;
	}

	/**
	 * Search the DB with the given restrictions.
	 * 
	 * Search results is updated by the result set of this operation before
	 * updating the view.
	 */
	public void addPlace() {
		assert (loginBean != null && loginBean.isLoggedIn());

		if (latitude == 0 && longitude == 0) {
			addMessage(new FacesMessage(FacesMessage.SEVERITY_INFO,
					"Add Place Warning",
					"A marker should be selected on the map"));
			return;
		}

		Place p = null;

		try {
			User user = userDAO.findByID(loginBean.getUserID());
			p = placeService.createPlace(placeName, country, city, 0, latitude,
					longitude, new Date(), tags, user);

		} catch (Exception e) {
			e.printStackTrace();
			addMessage(new FacesMessage(FacesMessage.SEVERITY_INFO,
					"Add Place Warning", "Error while adding place"));
			return;
		}

		if (p == null) {
			addMessage(new FacesMessage(FacesMessage.SEVERITY_INFO,
					"Add Place Warning", "Error while adding place"));
		} else {
			addMessage(new FacesMessage(FacesMessage.SEVERITY_INFO,
					"Add Place", "Place is successfully added"));
		}
	}

	/**
	 * Update the lat/lng
	 * 
	 * @param event
	 */
	public void onPointSelect(PointSelectEvent event) {
		LatLng latlng = event.getLatLng();
		map.getMarkers().clear();
		map.addOverlay(new Marker(latlng, "new_place"));
		latitude = latlng.getLat();
		longitude = latlng.getLng();
	}

	public void addMessage(FacesMessage message) {
		FacesContext.getCurrentInstance().addMessage(null, message);
	}

	public MapModel getMap() {
		return map;
	}

	public void setMap(MapModel map) {
		this.map = map;
	}

	public void onMarkerSelect(OverlaySelectEvent event) {
		marker = (Marker) event.getOverlay();
	}

	public Marker getMarker() {
		return marker;
	}

	public static List<Tag> completeTags(String query) {
		return FreebaseQuery.completeTags(query);
	}

	public List<Tag> getTags() {
		return tags;
	}

	public void setTags(List<Tag> tags) {
		this.tags = tags;
	}

	public LoginBean getLoginBean() {
		return loginBean;
	}

	public void setLoginBean(LoginBean loginBean) {
		this.loginBean = loginBean;
	}

	public PlaceDAO getPlaceDAO() {
		return placeDAO;
	}

	public void setPlaceDAO(PlaceDAO placeDAO) {
		this.placeDAO = placeDAO;
	}

	public List<String> completeCountry(String query) {
		if (query.length() > 1)
			return FreebaseQuery.completeCountry(query);
		else
			return null;
	}

	/**
	 * Auto completes the given city
	 * 
	 * @param query
	 * @return
	 */
	public List<String> completeCity(String query) {
		if (query.length() > 1)
			if (StringUtils.isEmpty(country)) {
				return FreebaseQuery.completeCity(query);
			} else {
				return FreebaseQuery.completeCity(country, query);
			}
		else
			return null;
	}

	/**
	 * Auto complete city using the country info
	 * 
	 * @param country
	 * @param query
	 * @return
	 */
	public List<String> completeCity(String country, String query) {
		if (query.length() > 1)
			if (StringUtils.isEmpty(country)) {
				return FreebaseQuery.completeCity(query);
			} else {
				return FreebaseQuery.completeCity(country, query);
			}
		else
			return null;
	}

	public PlaceService getPlaceService() {
		return placeService;
	}

	public void setPlaceService(PlaceService placeService) {
		this.placeService = placeService;
	}

	public UserDAO getUserDAO() {
		return userDAO;
	}

	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}
}
